package self.zhangkang.chart.view.kline.index

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import self.zhangkang.chart.data.KLineInfo
import self.zhangkang.chart.tools.CanvasTools
import self.zhangkang.chart.tools.NumberFormatUtils
import self.zhangkang.chart.view.IndexLineInfo
import self.zhangkang.chart.view.IndexNameConfig
import self.zhangkang.chart.view.kline.KLineIndex
import self.zhangkang.chart.view.kline.KLineIndexInfo
import self.zhangkang.chart.view.kline.KLineViewColor
import self.zhangkang.chart.view.kline.KLineViewDimen
import self.zhangkang.chart.view.pool.PathPool
import self.zhangkang.chart.view.pool.RectPool

/**
 * @author : Android-张康
 * created on: 2023/5/9 18:19
 * description:
 */
internal class KLineTurnOver(
    private val pathPool: PathPool,
    private val rectPool: RectPool,
    private val kLineViewColor: KLineViewColor,
    private val kLineViewDimen: KLineViewDimen,
    private val indexNameConfig: IndexNameConfig
) : KLineIndexInfo {

    private val turnoverMa5 = object : IndexLineInfo {

        override fun getName(): String {
            return "MA5"
        }

        override fun getLineColor(): Int {
            return Color.parseColor("#F09636")
        }

        override fun getIndexValue(kLineInfo: KLineInfo): Float {
            return kLineInfo.turnoverMa5
        }
    }

    private val turnoverMa10 = object : IndexLineInfo {

        override fun getName(): String {
            return "MA10"
        }

        override fun getLineColor(): Int {
            return Color.parseColor("#4988DF")
        }

        override fun getIndexValue(kLineInfo: KLineInfo): Float {
            return kLineInfo.turnoverMa10
        }
    }

    private val indexLineInfoList = mutableListOf(
        turnoverMa5,
        turnoverMa10
    )

    private val indexLineInfoPath = mutableMapOf<IndexLineInfo, Path>()

    private var maxValue: Long = 0

    private var minValue: Long = 0

    private var priceItem: Float = 0.0F

    private var volumeWidth: Float = 0.0F

    /**
     * 是否可以切换
     *
     * @return true 可以切换，false 不可以切换
     */
    override fun canSwitch(): Boolean {
        return getIndexInfo().canSwitch
    }

    /**
     * 是否点击到名称
     *
     * @param startX 开始X
     * @param startY 开始Y
     * @param stopX 结束X
     * @param stopY 结束Y
     * @param touchX 触摸的 X
     * @param touchY 触摸的 Y
     * @param textPaint 文字的画笔
     *
     * @return true 是，false 否
     */
    override fun isClickInName(
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        touchX: Float,
        touchY: Float,
        textPaint: Paint
    ): Boolean {
        val textBoundsRect = rectPool.acquire()
        //先绘制指标名称
        CanvasTools.getDrawTextBounds(
            startX = startX,
            startY = startY,
            stopY = stopY,
            textPaint = textPaint,
            indicatorName = getIndexInfo().indexName,
            indexNameConfig = indexNameConfig,
            textBoundsRect = textBoundsRect,
            hasArrowDropDown = canSwitch(),
        )
        val contains = textBoundsRect.contains(touchX.toInt(), touchY.toInt())
        rectPool.release(textBoundsRect)
        return contains
    }

    /**
     * 获取指标类型
     */
    override fun getIndexInfo(): KLineIndex {
        return KLineIndex.TurnOver
    }

    override fun getProportion(): Int {
        return 15
    }

    /**
     * 计算最大值前
     *
     * @param kLineInfo 第一个值
     */
    override fun calculationMaxAndMinBefore(kLineInfo: KLineInfo) {
        maxValue = 0
    }

    /**
     * 计算最大值
     *
     * @param kLineInfo 当前值
     */
    override fun calculationMaxAndMin(kLineInfo: KLineInfo) {
        if (kLineInfo.turnVolume > maxValue) {
            maxValue = kLineInfo.turnVolume
        }
    }

    /**
     * 计算最大值后
     */
    override fun calculationMaxAndMinAfter() {

    }

    override fun drawBackground(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        linePaint: Paint,
        textPaint: Paint
    ) {
        val backgroundPath = pathPool.acquire().apply {
            moveTo(startX, startY)
            lineTo(stopX, startY)
            lineTo(stopX, stopY)
            lineTo(startX, stopY)
            close()
        }
        canvas.drawPath(backgroundPath, linePaint)
        pathPool.release(backgroundPath)
        //绘制最高价
        textPaint.textSize = kLineViewDimen.ordinateTextSize
        textPaint.color = kLineViewColor.ordinateTextColor
        val maxValueText = maxValue.toString()
        val mTextBoundsRect = rectPool.acquire()
        textPaint.getTextBounds(maxValueText, 0, maxValueText.length, mTextBoundsRect)
        val textStartY = mTextBoundsRect.height() + kLineViewDimen.textPaddingLine + startY
        canvas.drawText(
            maxValueText,
            startX + kLineViewDimen.textPaddingLine,
            textStartY,
            textPaint
        )
        rectPool.release(mTextBoundsRect)
    }

    override fun drawCurrentIndexInfo(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        linePaint: Paint,
        textPaint: Paint,
        marginTop: Float,
        span: Int,
        indexValueHorizontalSpace: Float,
        indexValueVerticalSpace: Float,
        kLineInfo: KLineInfo,
        kLineIsLine: Boolean
    ) {
        //先绘制指标名称
        val indicatorNameWidth = CanvasTools.drawIndicatorName(
            canvas = canvas,
            startX = startX,
            startY = startY,
            stopY = stopY,
            linePaint = linePaint,
            textPaint = textPaint,
            rectPool = rectPool,
            indicatorName = getIndexInfo().indexName,
            indexNameConfig = indexNameConfig,
            hasArrowDropDown = canSwitch()
        )
        textPaint.textSize = kLineViewDimen.indexValueTextSize
        var indicatorStart = indicatorNameWidth + indexValueHorizontalSpace
        var drawTextInVerticalCenter = CanvasTools.drawTextInVerticalCenter(
            canvas,
            indicatorStart,
            startY,
            stopY,
            kLineInfo.turnVolume.toString(),
            textPaint,
            rectPool = rectPool
        )
        indicatorStart += drawTextInVerticalCenter + indexValueHorizontalSpace
        indexLineInfoList.forEach { maInfo ->
            val indexValue = maInfo.getIndexValue(kLineInfo)
            val currentString = buildString {
                append(maInfo.getName())
                append(":")
                if (indexValue.isFinite()) {
                    append(NumberFormatUtils.numberFormat(indexValue))
                } else {
                    append("--")
                }
            }
            textPaint.color = maInfo.getLineColor()
            drawTextInVerticalCenter = CanvasTools.drawTextInVerticalCenter(
                canvas, indicatorStart, startY, stopY, currentString, textPaint, rectPool = rectPool
            )
            indicatorStart += drawTextInVerticalCenter + indexValueHorizontalSpace
            indexLineInfoPath[maInfo] = pathPool.acquire()
        }
    }

    override fun beforeDrawItemContent(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        paint: Paint,
        candlestickWidth: Float,
        candlestickWidthSpace: Float,
        kLineInfo: KLineInfo,
        kLineIsLine: Boolean
    ) {
        val volumeSpace: Float = if (kLineIsLine) {
            0F
        } else {
            kLineViewDimen.volumeRectSpace
        }
        val volumeRange = maxValue - minValue
        val drawHeight = stopY - startY
        priceItem = drawHeight / volumeRange
        volumeWidth = candlestickWidth + candlestickWidthSpace - volumeSpace
    }

    override fun drawItemContent(
        canvas: Canvas,
        startX: Float,
        startY: Float,
        stopX: Float,
        stopY: Float,
        textPaint: Paint,
        linePaint: Paint,
        kLineInfo: KLineInfo,
        isFirst: Boolean,
        yangLineIsFill: Boolean,
        totalTranslateX: Float,
        candlestickWidth: Float,
        halfCandlestickWidth: Float,
        kLineIsLine: Boolean
    ) {
        //最高价格的 Y 坐标
        val volumeY = priceItem * (maxValue - kLineInfo.turnVolume) + startY
        //Path 的横坐标
        var pathX = halfCandlestickWidth + totalTranslateX
        if (pathX < 0) {
            pathX = halfCandlestickWidth
        }
        indexLineInfoPath.forEach {
            val maValue = it.key.getIndexValue(kLineInfo)
            val maY = priceItem * (maxValue - maValue) + startY
            val path = it.value
            if (isFirst) {
                if (maY <= stopY) {
                    path.moveTo(pathX, maY)
                } else {
                    path.moveTo(pathX, stopY)
                }
            } else {
                if (maY < stopY) {
                    path.lineTo(pathX, maY)
                }
            }
        }
        //判断当前绘制的颜色
        val candlestickColor = if (kLineInfo.closePrice > kLineInfo.openPrice) {
            if (!yangLineIsFill) {
                linePaint.style = Paint.Style.STROKE
            }
            kLineViewColor.redColor
        } else if (kLineInfo.closePrice < kLineInfo.openPrice) {
            linePaint.style = Paint.Style.FILL_AND_STROKE
            kLineViewColor.greenColor
        } else {
            linePaint.style = Paint.Style.FILL_AND_STROKE
            kLineViewColor.grayColor
        }
        linePaint.color = candlestickColor
        linePaint.strokeWidth = kLineViewDimen.borderLineStrokeWidth
        val rectLeft: Float = if (totalTranslateX > 0) {
            startX - kLineViewDimen.volumeRectSpace
        } else {
            startX
        }
        val rectRight: Float = if (isFirst) {
            rectLeft + volumeWidth - kLineViewDimen.borderLineStrokeWidth * 2
        } else {
            rectLeft + volumeWidth
        }
        //绘制矩形
        canvas.drawRect(startX, volumeY, rectRight, stopY, linePaint)
    }

    override fun afterDrawItemContent(canvas: Canvas, paint: Paint) {
        paint.strokeWidth = kLineViewDimen.indexLineStrokeWidth
        indexLineInfoPath.forEach {
            val maColor = it.key.getLineColor()
            val maPath = it.value
            paint.color = maColor
            canvas.drawPath(maPath, paint)
            pathPool.release(maPath)
        }
        indexLineInfoPath.clear()
    }

    /**
     * 获取当前左边的值
     *
     * @param percentage 比例
     *
     * @return 返回当前左边坐标的值
     */
    override fun getCurrentLeftValue(percentage: Float): String? {
        return null
    }

    /**
     * 获取当前右边的值
     *
     * @param percentage 比例
     *
     * @return 返回当前右边坐标的值
     */
    override fun getCurrentRightValue(percentage: Float): String? {
        return null
    }
}